package com.oxygen.pt.controller;

import ch.qos.logback.classic.Logger;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.PageInfo;
import com.google.zxing.NotFoundException;
import com.oxygen.pt.pojo.dto.DistributionCabinDTO;
import com.oxygen.pt.pojo.dto.PatientDTO;
import com.oxygen.pt.pojo.entity.Patient;
import com.oxygen.pt.pojo.vo.*;
import com.oxygen.pt.service.PatientService;
import com.oxygen.pt.utils.QRCodeUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

@RestController()
@RequestMapping("/patient")
@Slf4j
public class PatientController {

    @Resource
    private PatientService patientService;

    @Resource
    private QRCodeUtils qrCodeUtils;

    @GetMapping("/hi")
    public String health(){
        return "hi,pt";
    }

    @PostMapping("/add")
    public Result<String> add(@RequestBody PatientDTO patientDTO){
        log.debug("添加患者的参数为：{}",patientDTO.toString());
        return patientService.add(patientDTO, (Logger) log);
    }

    /**
     * 通用更新患者信息接口
     * 对应前端的 axios.put(`http://localhost:8081/patient/${this.formData.patientId}`, this.formData)
     */
    @PutMapping("/{id}")
    public Result<String> updatePatient(@PathVariable("id") Long id, @RequestBody PatientDTO patientDTO) {
        log.info("收到更新患者信息的 PUT 请求，路径中的患者ID: {}", id);
        log.debug("请求体中的患者数据: {}", patientDTO.toString());

        // 调用 Service 层的方法进行更新
        // 您需要在 PatientService 中实现 updatePatient 方法
        boolean success = patientService.updatePatient(patientDTO); // 假设您的 Service 返回一个布尔值表示成功或失败
        if (success) {
            return Result.success("患者信息更新成功！");
        } else {
            return Result.error("更新失败，患者ID不存在或数据处理异常。");
        }
    }
    /**
     * 根据ID删除患者信息
     * @param id 患者ID
     * @return 返回操作结果
     */
    @DeleteMapping("/{id}")
    public Result<String> deletePatient(@PathVariable String id) {
        long idL = Long.parseLong(id);
        log.info("准备删除ID为 {} 的患者", idL);
        boolean success = patientService.deletePatientById(idL);
        if (success) {
            return Result.success("患者删除成功");
        }
        return Result.error("删除失败或该患者不存在");
    }

    /**
     * 分页 和筛选查询患者的详情信息
     * @param costType 患者的费用类别
     * @param gender 患者的性别 0为女性 1为男性
     * @param minAge 执行患者筛选时的年龄范围 最小值
     * @param maxAge 执行患者筛选时的年龄范围 最大值
     * @param personType 人员类别
     * @param page 第几页
     * @param size 每页多少条数据
     * @return 返回查询的患者信息列表
     */
    @GetMapping("/list")
    public Result<PageInfo<PatientVO>> getPatients(
            @RequestParam(required = false) String costType,
            @RequestParam(required = false) Integer gender,
            @RequestParam(required = false) Long minAge,
            @RequestParam(required = false) Long maxAge,
            @RequestParam(required = false) Long personType,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size) {
        log.info("接收到的参数为,{},{},{},{},{},{},{}",costType, gender, minAge, maxAge, personType, page, size);
        PageInfo<PatientVO> patients = patientService.getPatients(costType, gender, minAge, maxAge, personType, page, size);
        return Result.success(patients);
    }

    /**
     * 根据id查询患者，用于扫码查询患者功能
     * @param id 查看详情患者的 id
     * @return 返回患者的详情信息
     */
    @GetMapping("/id/{id}")
    public Result<PatientVO> getPatientById(@PathVariable Long id){
        log.info("接收到的患者id为{}",id);
        PatientVO patient = patientService.getById(id);
        if (patient == null){
            return Result.error("为查询到id为"+ id +"的患者数据");
        }
        return Result.success(patient);
    }

    @GetMapping("/detailById/{id}")
    public Result<Object>  patientDetail(@PathVariable Long id){
        log.info("查询患者治疗详情的id为：{}",id);
        PatientDetailVO patientDetail =  patientService.getDetailById(id);
        return Result.success(patientDetail);
    }

    /**
     * 患者异常记录（PageHelper 分页）
     * @param pageNum  当前页，默认 1
     * @param pageSize 每页条数，默认 10
     */
    @GetMapping("/anomalyRecord/list")
    public Result<PageInfo<AnomalyRecordVO>> anomalyRecordList(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize) {

        log.info("查询异常记录分页请求：pageNum={}, pageSize={}", pageNum, pageSize);
        PageInfo<AnomalyRecordVO> pageInfo = patientService.getAnomalyPage(pageNum, pageSize);
        return Result.success(pageInfo);
    }

    @PostMapping("/insertAnomalyRecord")
    public Result<Object> insertAnomalyRecord(@RequestBody AnomalyRecordVO anomalyRecordVO) {
        return patientService.insertAnomalyRecord(anomalyRecordVO);
    }

    /**
     * 治疗数据统计
     * @param unit 统计的时间单位 月，季度，年(1: 周 2：月 3： 季度 4：本年)
     * @return 患者列表
     */
    @GetMapping("/treatmentData/{unit}")
    public Result<Object> treatmentData(@PathVariable Integer unit){
        TreatmentAnalysisVO treatmentData = patientService.treatmentData(unit);
        return Result.success(treatmentData);
    }

    /**
     *地方人员和政府人员的数量统计
     * @return
     */
    @GetMapping("/armyAndPlaceNum")
    public Result<Object> armyAndPlaceNum(){
        ArmyAndPlaceVO armyAndPlaceVO =  patientService.getArmyAndPlaceNum();
        return Result.success(armyAndPlaceVO);
    }

    /**
     * 获取患者类型的数量
     * @return 各个患者类型的数量
     */
    @GetMapping("/patientTypeNumCount")
    public Result<Object> patientTypeNumCount(){
        PatientTypeNumCountVO count = patientService.getPatientTypeNumCount();
        return Result.success(count);
    }

    /**
     * 为患者分配舱室
     * @param distributionCabinDTO  患者的id：patient_id和舱号 cabinNumber
     * @return 有余量则会添加成功，无余量则添加失败
     */
    @PostMapping("/distributionCabin")
    public Result<Object> distributionCabin(@RequestBody DistributionCabinDTO distributionCabinDTO){
        Result<Object> result = patientService.distributionCabin(distributionCabinDTO);
        return Result.success(result);
    }

    /**
     * 修改患者状态 由已经分配到舱中 取消分配 状态切换到未分配的状态
     * @return Result 统一信息返回
     */
    @PutMapping("/cancelAllocation/{patientId}")
    public Result<Object> cancelAllocation(@PathVariable String patientId){
        long id = Long.parseLong(patientId);
        return patientService.cancelAllocation(id);
    }

    /**
     * 患者开始治疗接口
     * @param patientId 患者ID
     * @return 返回操作是否成功
     */
    @PutMapping("/startTreatment/{patientId}")
    public Result<Object> startTreatment(@PathVariable String patientId){
        long id = Long.parseLong(patientId);
        return patientService.startTreatment(id);
    }

    @PutMapping("/finishTreatment/{patientId}")
    public Result<Object> finishTreatment(@PathVariable String patientId){
        long id = Long.parseLong(patientId);
        return patientService.finishTreatment(id);
    }

    /**
     * 二维码生成接口，
     * @param id 患者的id
     * @return 一个含二维码字节数组的
     * @throws IOException 文件读取异常
     */
    @GetMapping("/qrById/{id}")
    public ResponseEntity<byte[]> getQrById(@PathVariable String id) throws IOException {
        long idL = Long.parseLong(id);
        File file = qrCodeUtils.creatQRImage(idL);
        log.info("查询到的患者的二维码为 {}", file.getAbsolutePath());
        // 读取文件到字节数组
        byte[] bytes = Files.readAllBytes(file.toPath());
        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_PNG); // 二维码是 PNG
        headers.setContentLength(bytes.length);
        // 如果想让浏览器下载而不是预览，用下面这句
        // headers.setContentDisposition(ContentDisposition.attachment().filename(file.getName()).build());
        return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
    }


    @PostMapping("/qr/upload")
    public Result<PatientVO> uploadQr(@RequestParam("qr") MultipartFile file) throws IOException, NotFoundException {
        // 1. 保存到磁盘 / OSS / 数据库
        // 0. 确保目录存在
        File dir = new File("src/main/resources/static/QRImage");
        if (!dir.exists())
            dir.mkdirs();
        // 1. 生成唯一文件名（时间戳+原后缀）

        String original = file.getOriginalFilename();
        String suffix   = original.substring(original.lastIndexOf("."));
        String fileName = System.currentTimeMillis() + suffix;
        File dest = new File(dir, fileName);

        // 2. 解析二维码里的文本
        String content = qrCodeUtils.decode(file.getInputStream());

        Patient bean = JSONUtil.toBean(content, Patient.class);
        log.info(bean.toString());
        PatientVO res = patientService.getById(Long.valueOf(bean.getPatientId()));
        return Result.success(res);   // 返回解析结果给前端
    }

}
